home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir34
/
qformat1.zip
/
ZAP.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-18
|
6KB
|
177 lines
// ZAP (quick format) disk
// Bad cluster information is retained!
#include <dos.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream.h>
#include <iomanip.h>
#include <ctype.h>
typedef unsigned char byte;
typedef unsigned int WORD;
typedef unsigned long dword;
const char NUL = '\0';
class dpb {
public:
byte driveno; // Drive number (0 == A:)
byte unit; // Unit number within driver
WORD bpers; // Bytes per sector
byte hisect; // Highest sector number in cluster
byte shift; // To convert clusters into sectors
WORD reserved; // Reserved sectors
byte nfats; // Number of FATs
WORD ndir; // Number of root directory entries
WORD data; // Number of first sector with user data
WORD ndata; // Highest cluster number + 1
// 16 bit FAT if > 0ff6
WORD sperf; // Sectors per FAT
WORD sdir; // Number of first directory sector
dpb far *dhdr; // Address of device driver header
byte media; // Media ID byte
byte clean; // 0 if disk accessedm else FF
dpb far *next; // Pointer to next DPB
WORD search; // Search start cluster, usually the last
// allocated
WORD nfree; // Number of free clusters on drive or FFFFh
WORD infolevel;
WORD Slo; // Serial # (low order word)
WORD Shi; // (high order word)
char label[11]; // Volume label
char ftype[8]; // File system type
unsigned *FAT; // Points to FAT buffer
char is16bit; // Set if 16 bit FAT
dpb(char); // Constructor
void list(); // List dpb to cout
void erase();
unsigned sector(unsigned);
unsigned getentry(unsigned);
void zapentry(unsigned);
};
dpb::dpb(char drv) // 0 == default drive!
{
void far *result; // Points to DOS copy of the dpb
asm {
push ds
mov dl,drv
and dl,15
mov ah,0x32
int 0x21
xor al,al
je okay
xor bx,bx
mov ds,bx
}
okay:
asm {
mov dx,ds
pop ds
}
result = MK_FP(_DX, _BX);
_fmemcpy((void *)this, result, 33);
_DX = (unsigned)&infolevel;
asm {
mov bl,drv
and bl,15
mov ax,0x6900
int 0x21
}
is16bit = ftype[4] == '6';
ftype[5] = NUL;
}
void dpb::list()
{
char save = *ftype; *ftype = NUL; // Temporary hack
cout.setf(ios::left);
cout << "\n\tDrive Parameter Block\n" <<
"\n\tDrive " << (char)('A' + driveno) <<
"\n\tBytes per sector " << bpers <<
"\n\tSectors per cluster " << (hisect + 1) <<
"\n\tClusters to sectors shift " << (int)shift <<
"\n\tReserved sectors " << reserved <<
"\n\tNumber of FATs " << (int)nfats <<
"\n\tNumber of root directory entries " << ndir <<
"\n\tFirst user data sector " << data <<
"\n\tNumber of data clusters " << (ndata - 1);
if (nfree != 65535) {
cout << "\n\tNumber of free clusters " << nfree ;}
cout << "\n\tSearch start cluster " << search <<
"\n\tSectors per FAT " << sperf <<
"\n\tFirst directory sector " << sdir <<
"\n\tMedia ID byte " << hex << (int)media <<
"\n\tSerial number " << Shi << ':' << Slo <<
"\n\tVolume label " << setw(11) << label;
*ftype = save; cout <<
"\n\tFile system type " << setw(8) << ftype <<
"\n\n";
}
void dpb::erase()
{
(void *)FAT = new char[sperf*bpers];
absread(driveno, sperf, 1L, FAT); // Read a FAT
for (int i = 2; i < ndata; i++) zapentry(i); // Kill real data clusters
if(abswrite(driveno, sperf , 1L, FAT)) { // Write FATs out
cout << "Cannot write on disk " << (char)('A'+driveno) << endl;
return;
}
abswrite(driveno, sperf , 1L + sperf, FAT);
delete FAT;
char *buf = (char *)calloc(bpers, 1); // Data for directory zap
for (i = 0; i < ndir/16; i++)
abswrite(driveno, 1, sdir + i, buf); // Zap directory
free(buf);
}
unsigned dpb::sector(unsigned cluster) // Convert cluster # to sector #
{
return ((cluster-2)<<shift) + data;
}
unsigned dpb::getentry(unsigned c) // Get FAT entry for cluster
{
if (is16bit) return FAT[c]; /* 16 bit FAT entry */
unsigned index = (3*c)>>1;
WORD word = *(WORD *)((char)FAT+index);
unsigned result = (c&1? word>>4: word&0xfff);
if (result >= 0xff0) result |= 0xf000;
return result;
}
void dpb::zapentry(unsigned c) // Zap cluster if not bad
{
if (is16bit) {if (FAT[c] != 0xfff7) FAT[c] = 0; return;} // Zap if not bad
unsigned index = (3*c)>>1;
WORD oldword = *(WORD *)((char *)FAT+index);
if (!(c&1)) oldword &= 0x0fff; else oldword >>= 4; // Position the entry
if (!oldword || oldword == 0xff7) return; // If free or bad, return
*(WORD *)((char *)FAT+index) &= ((c&1)? 0x000f: 0xf000); // Zap it
}
void main(int, char *argv[])
{
dpb *disk = new dpb(*argv[1]);
disk->list();
for (;;) {
if (disk->driveno > 1) cout << "This is a hard disk!!!\a" << endl;
cout << "Do you really want to zap this disk (Y/N)? " << flush;
char k; cin >> k; k = tolower(k);
if (k == 'n') return;
if (k == 'y') break;
}
disk->erase();
char buf[10];
sprintf(buf, "chkdsk %c:", 'a' + disk->driveno);
system(buf);
}